package cn.exlu.coco.core.server.socket;

import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ChatManager;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.ConnectionListener;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;

import cn.exlu.coco.core.exception.CoCoException;



public class XmppServer {
    
    private boolean isDebug = false;

    private XMPPConnection mXmppConnection = null;
    
    private String username;
    private String passwd;
    private String serverAddr;
    private int servierPort;

    public XmppServer(String username, String passwd, String serverAddr,
            int servierPort){
    	this.username = username;
    	this.passwd = passwd;
    	this.serverAddr = serverAddr;
    	this.servierPort = servierPort;
    }


    public boolean isDebug() {
        return isDebug;
    }

    public void setDebug(boolean isDebug) {
        this.isDebug = isDebug;
    }



    /**
     * 创建报文
     * @param msgContent
     * @return
     */
    private static org.jivesoftware.smack.packet.Message createMessage(String msgContent) {
        org.jivesoftware.smack.packet.Message msg = new org.jivesoftware.smack.packet.Message();
        msg.setType(org.jivesoftware.smack.packet.Message.Type.chat);
        msg.setBody(msgContent);
        return msg;
    }
    
    public void sendMsgChat(String msgContent, String toUser) throws CoCoException, XMPPException{
     // 链接XMPP
        connectXmpp();
        
        ChatManager cm = mXmppConnection.getChatManager();
        
        Chat chat = cm.createChat(toUser, null);
        
        chat.sendMessage(msgContent);
        
    }
    

    /**
     * 发送报文
     * @param packet
     * @param toUser
     * @throws CoCoException
     */
    public void sendMsg(String msgContent,
            String toUser) throws CoCoException {
        
        if(isDebug){
            return;
        }
    	
    	org.jivesoftware.smack.packet.Message msg = createMessage(msgContent);
    	
        // 链接XMPP
        connectXmpp();

        // mPacket = packet;
        if (mXmppConnection != null) {
            try {
            	msg.setTo(toUser);
                mXmppConnection.sendPacket(msg);
            } catch (IllegalStateException e) {
//                _LOG.error("xmppmsg:" + packet.getFrom() + ">>" + packet.getTo() + " : " + packet.getBody());
//                _LOG.error("Not connected to server catch", e);
                throw new CoCoException("Not connected to server catch");
            } catch (Exception e) {
//                _LOG.error("xmppmsg:" + packet.getFrom() + ">>" + packet.getTo() + " : " + packet.getBody());
//                _LOG.error("send Message fail", e);
                throw new CoCoException("send Message fail");
            }
        }
    }

    /**
     * 关闭连接
     */
    public boolean disConnectXmpp(){
        if(mXmppConnection == null){
            return true;
        }
        if(mXmppConnection.isConnected()){
            mXmppConnection.disconnect();
            return true;
        }
        
        return true;
    }

    /**
     * 打开连接
     * @param username
     * @param passwd
     * @param serverAddr
     * @param port
     * @throws CoCoException
     */
    public boolean connectXmpp() throws CoCoException{
        
        if(isDebug){
            return true;
        }
        
        if(mXmppConnection == null || !mXmppConnection.isConnected()){

        }else{
//            mXmppConnection.disconnect();
            return true;
        }

        ConnectionConfiguration conf = new ConnectionConfiguration(this.serverAddr,
        		this.servierPort);
        conf.setReconnectionAllowed(true);
        mXmppConnection = new XMPPConnection(conf);
        try {
            if(mXmppConnection.isConnected()){
                return true;
            }
            mXmppConnection.connect();

            // 添加侦听事件
            mXmppConnection.addConnectionListener(new ConnectionListener() {
                
                public void reconnectionSuccessful() {
                    System.out.println("打开连接成功");
                }

                public void reconnectionFailed(Exception arg0) {
                    System.out.println("打开连接失败");
                }

                public void reconnectingIn(int arg0) {
                    System.out.println("再次打开连接：reconnectingIn");
                }

                public void connectionClosedOnError(Exception arg0) {
                    System.out.println("关闭连接失败：connectionClosedOnError");
                    if (arg0.getMessage().contains("conflict")) {
                        mXmppConnection.disconnect();
                    }

                }

                public void connectionClosed() {
//                    _LOG.info("连接已关闭.");
                }
            });

        } catch (XMPPException e) {
//            _LOG.error("连接失败：connect:crash", e);
            throw new CoCoException("connect:crash");
        } catch (IllegalStateException e) {
//            _LOG.error("连接失败：Not connected to server catch", e);
            throw new CoCoException("Not connected to server catch");
        }

        try {
            mXmppConnection.login(this.username, this.passwd);
        } catch (XMPPException e) {
//            _LOG.error("连接失败：Not connected to server catch", e);
            throw new CoCoException("Not connected to server catch");
        } catch (NullPointerException e){
//            _LOG.error("连接失败：Not connected to server catch", e);
            throw new CoCoException("Not connected to server catch");
        } catch (IllegalStateException e) {
//            _LOG.error("连接失败：Not connected to server catch", e);
            throw new CoCoException("Not connected to server catch");
        }
        
        return true;
    }

    
}
